package com.ease.dao.ibatis.typehandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.ease.common.enums.EnumUtil;
import com.ease.common.enums.ValuableEnum;
import com.ease.common.util.Detect;
import com.ease.common.util.ReflectionUtil;
import com.ibatis.sqlmap.engine.type.TypeHandler;

/**
 * 
 * @author nathanleewei
 * 
 */
public abstract class ValuableEnumTypeHandler<T extends ValuableEnum> extends Detect implements TypeHandler {

	protected Class<T> mappedClass;

	@SuppressWarnings("unchecked")
	protected T getResult(short value) {
		if (value > 0) {
			if (null != mappedClass) {
				return EnumUtil.get(mappedClass, value);
			}
			return EnumUtil.get((Class<T>) ReflectionUtil.getGenericType(this.getClass()), value);
		} else {
			return (T) null;
		}
	}

	public void setParameter(PreparedStatement ps, int i, Object parameter, String jdbcType) throws SQLException {
		if (null != parameter) {
			ValuableEnum object = (ValuableEnum) parameter;
			ps.setShort(i, object.getValue());
		} else {
			ps.setNull(i, oracle.jdbc.OracleTypes.NUMBER);
		}
	}

	public Object getResult(ResultSet rs, String columnName) throws SQLException {
		return getResult(rs.getShort(columnName));
	}

	public Object getResult(CallableStatement cs, int columnIndex) throws SQLException {
		return getResult(cs.getShort(columnIndex));
	}

	public Object getResult(ResultSet rs, int columnIndex) throws SQLException {
		return getResult(rs.getShort(columnIndex));
	}

	public Object valueOf(String value) {
		if (notEmpty(value) && !"null".equalsIgnoreCase(value)) {
			return getResult(Short.parseShort(value));
		}
		return null;
	}

	public boolean equals(Object object, String string) {
		if (object == null || string == null) {
			return object == string;
		} else {
			Object castedObject = valueOf(string);
			return object.equals(castedObject);
		}
	}

	/**
	 * @return the mappedClass
	 */
	public Class<T> getMappedClass() {
		return mappedClass;
	}

	/**
	 * @param mappedClass
	 *            the mappedClass to set
	 */
	public void setMappedClass(Class<T> mappedClass) {
		this.mappedClass = mappedClass;
	}

}
